#include "adc.h"
#include "cw32f030_rcc.h"
#include "cw32f030_gpio.h"
#include "cw32f030_adc.h"
#include "cw32f030_btim.h"

static void Btim2_Configuration(void)
{
    BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct;
    __RCC_BTIM_CLK_ENABLE();

    /* NVIC Configuration */
    NVIC_EnableIRQ(BTIM2_IRQn); // 配置BTIM2中断

    BTIM_TimeBaseInitStruct.BTIM_Mode      = BTIM_Mode_TIMER;
    BTIM_TimeBaseInitStruct.BTIM_Period    = 1000 - 1;       // 125us触发1次
    BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV64; // 8MHZ
    BTIM_TimeBaseInitStruct.BTIM_OPMode    = BTIM_OPMode_Repetitive;

    BTIM_TimeBaseInit(CW_BTIM2, &BTIM_TimeBaseInitStruct);
    BTIM_ITConfig(CW_BTIM2, BTIM_IT_OV, ENABLE);
    BTIM_Cmd(CW_BTIM2, ENABLE);
}

void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStructure;         // ADC配置结构体
    ADC_SerialChTypeDef ADC_SerialChStructure; // ADC序列通道结构体
    GPIO_InitTypeDef GPIO_Init_Struct;

    __RCC_GPIOB_CLK_ENABLE(); // 打开ADC对应引脚时钟
    __RCC_ADC_CLK_ENABLE();   // 打开ADC时钟

    PB01_ANALOG_ENABLE(); // 使能模拟引脚
    PB00_ANALOG_ENABLE(); // 使能模拟引脚
    PB10_ANALOG_ENABLE(); // 使能模拟引脚
    PB11_ANALOG_ENABLE();

    GPIO_Init_Struct.IT   = GPIO_IT_NONE;
    GPIO_Init_Struct.Mode = GPIO_MODE_ANALOG;                                    // 将GPIO的模式配置成模拟功能
    GPIO_Init_Struct.Pins = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_0 | GPIO_PIN_1; // PB10是电压采集引脚
    GPIO_Init(CW_GPIOB, &GPIO_Init_Struct);

    ADC_StructInit(&ADC_InitStructure);           // ADC默认值初始化
    ADC_InitStructure.ADC_ClkDiv = ADC_Clk_Div32; // ADC工作时钟配置 PCLK/32 = 64/32 = 2Mhz

    /*信号电压较低时，可以降低参考电压来提高分辨率。 改变参考电压后，同样二进制表示的电压值就会不一样，
      最大的二进制（全1）表示的就是你的参考电压，在计算实际电压时，就需要将参考电压考虑进去。*/
    ADC_InitStructure.ADC_VrefSel    = ADC_Vref_BGR1p5;   // 参考电压设置为1.5V
    ADC_InitStructure.ADC_SampleTime = ADC_SampTime10Clk; // 由于电压信号为慢速信号，ADC采样时间为十个ADC采样周期以确保准确

    ADC_SerialChStructure.ADC_SqrEns     = ADC_SqrEns01; // Sqr为序列配置寄存器，这里只用到了序列0的通道，所以配置成0表示只转换Sqr0序列
    ADC_SerialChStructure.ADC_Sqr0Chmux  = ADC_SqrCh11;  // 配置ADC序列，PB10是ADC的第11通道
    ADC_SerialChStructure.ADC_Sqr1Chmux  = ADC_SqrCh12;
    ADC_SerialChStructure.ADC_InitStruct = ADC_InitStructure; // ADC初始化

    ADC_SerialChContinuousModeCfg(&ADC_SerialChStructure); // ADC序列连续转换模式配置
    ADC_ClearITPendingAll();                               // 清除ADC所有中断状态
    ADC_Enable();                                          // ADC使能
    ADC_SoftwareStartConvCmd(ENABLE);                      // ADC转换软件启动命令
    Btim2_Configuration();
}

static uint16_t voltage;
static uint16_t current;

void calculated_voltage(void)
{
    ADC_GetSqr0Result(&voltage);
    voltage = (voltage * 1500 >> 12) * (220 + 10) / 100; // v
}

uint16_t get_voltage(void)
{
    return voltage;
}

void calculated_current(void)
{
    ADC_GetSqr1Result(&current);
    current = 10 * current * 1500 >> 12; // mv
}

uint16_t get_current(void)
{
    return current;
}